在了解過Day14 從原始碼安裝庫 和 Day16 使用包管理器安裝庫這兩種不同的安裝方法後,今天就來介紹軟體發布的流程。
首先,當我們進行軟體版本的更新時,如果這次的變更不涉及主版本號的提升,那麼我們就需要使用Debug模式來編譯原始碼後,讓ABI cheacker 檢查庫的程式介面(API)與二進制接口(ABI),確保它是否與之前的版本保持一致的相容性,否則有可能使用者無法正確使用新版本的庫。
檢查完後,接下來在進行軟體發布時,通常會使用 Release 模式來編譯原始碼,這個模式會優化程式碼,以提高執行效能。
ABI Compliance Cheacker的主要功能是分析 API/ABI(程式介面/二進制接口)中的變更。
這個工具的操作方式是建立並比較庫的頭文件和共享物件的 ABI 。如果共享物件包含偵錯訊息(就是以Debug模式編譯專案),也可以使用 ABI Dumper 工具( https://github.com/lvc/abi-dumper )追蹤 C/C++ 庫或核心模組的 ABI 變更 。
這個工具的主要使用場景是針對軟體庫開發人員以及 Linux 系統維護人員。它特別適用於那些希望確保向後相容性的場景,這意味著舊版應用程式可以繼續運行,或者可以使用新版的庫重新編譯,而不會出現問題。這對於軟體庫的穩定性和可靠性非常重要,特別是在不斷演進的軟體環境中。
$ sudo apt-get install -y elfutils
P.S. 基本上只要安裝這個額外的依賴就能動了,如果編譯過程中有錯誤,請參考GitHub頁面中的需求
$ git clone https://github.com/lvc/abi-compliance-checker.git
$ cd abi-compliance-checker
$ sudo make install prefix=/usr
$ git clone https://github.com/lvc/abi-dumper.git
$ cd abi-dumper
$ sudo make install prefix=/usr
定義:專案的建構方式
SET(CMAKE_BUILD_TYPE "Debug") # 將專案的建構方式設定為 Debug 模式
SET(CMAKE_BUILD_TYPE "Release") # 將專案的建構方式設定為 Release 模式
$ cmake -DCMAKE_BUILD_TYPE=Debug // 將專案的建構方式設定為 Debug 模式
$ cmake -DCMAKE_BUILD_TYPE=Release // 將專案的建構方式設定為 Release 模式
$ abi-dumper <OLD.so> -o <ABI-0.dump> -lver 0
$ abi-dumper <NEW.so> -o <ABI-1.dump> -lver 1
$ abi-compliance-checker -l NAME -old <ABI-0.dump> -new <ABI-1.dump>
範例會用採用Day13一樣的方式依序更新並使用ABI Compliance Cheacker
$ git clone https://github.com/m11112089/2023_iT_CMake.git
$ cd ~/2023_iT_CMake/Day17/MathFunctions
1. 使用 Debug 模式編譯1.0.0版本
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
2. 更新 MathFunctions/src/mysqrt.cpp 原始碼
//mysqrt 1.0.0
#include "mysqrt.h"
#include <iostream>
double sqrt(double x)
{
if (x <= 0) return 0;
double result = x;
for (int i = 0; i < 5; ++i) {
if (result <= 0) {
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << i << "Computing sqrt of " << x << " to be " << result << std::endl;
}
return result;
}
3. 更新 MathFunctions/CMakeLists.txt 動態庫版本號為 1.0.1
project(MathFunctions VERSION 1.0.1 LANGUAGES CXX)
# 設定專案名稱為MathFunctions,版本為1.0.1,且此項目使用C++
4. 使用 Debug 模式編譯1.0.1版本
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
5. 進入lib資料夾比較新舊版本差異
$ abi-dumper libmysqrt.so.1.0.0 -o 1.0.0.dump -lver 1.0.0
$ abi-dumper libmysqrt.so.1.0.1 -o 1.0.1.dump -lver 1.0.1
kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump <------- 生成的.dump文件⭐
├── 1.0.1.dump <------- 生成的.dump文件⭐
├── libmysqrt.so -> libmysqrt.so.1
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
└── libmysqrt.so.1.0.1
$ abi-compliance-checker -l NAME -old 1.0.0.dump -new 1.0.1.dump
生成的報表文件 compat_report.html 可以用google打開,在二進制相容性與原始碼相容性的 test Results 那一欄可以發現是100%
kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump
├── 1.0.1.dump
├── compat_reports
│ └── NAME
│ └── 1.0.0_to_1.0.1
│ └── compat_report.html <----- 生成的報表⭐
├── libmysqrt.so -> libmysqrt.so.1
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
└── libmysqrt.so.1.0.1
6. 確認過沒有相容性問題後使用 Release 模式重新發布1.0.1版本
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make
P.S. 如果使用 Release 模式編譯時生成 .dump 文件會發現出現 ERROR ,因為 ABI Compliance Cheacker 需要 Debug 模式產生的 Debug information 來生成比較報表。
kai@esoc:~/2023_iT_CMake/Day17/lib$ abi-dumper libmysqrt.so.1.0.1 -o 1.0.1.dump -lver 1.0.1
Reading v-tables
ERROR: cannot find 'vtable-dumper'
ERROR: can't find debug info in object(s)
1. 先將剛剛使用 Release 模式編譯的1.0.1改回 Debug 模式
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
2. 更新 MathFunctions/src/mysqrt.cpp 和 MathFunctions/include/mysqrt.h 原始碼
//mysqrt 2.0.0
#include "mysqrt.h"
#include <iostream>
double sqrt(double x, int iterations)
{
if (x <= 0) return 0;
double result = x;
for (int i = 0; i < iterations; ++i) {
if (result <= 0) {
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << i << "Computing sqrt of " << x << " to be " << result << std::endl;
}
return result;
}
//mysqrt.h 2.0.0
#ifndef MYSQRT_H
#define MYSQRT_H
double sqrt(double x, int iterations);
#endif // MYSQRT_H
3. 更新 MathFunctions/CMakeLists.txt 動態庫版本號為 2.0.0
project(MathFunctions VERSION 2.0.0 LANGUAGES CXX)
# 設定專案名稱為MathFunctions,版本為2.0.0,且此項目使用C++
4. 使用 Debug 模式編譯2.0.0版本
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
5. 進入lib資料夾比較新舊版本差異
$ abi-dumper libmysqrt.so.2.0.0 -o 2.0.0.dump -lver 2.0.0
$ abi-compliance-checker -l NAME -old 1.0.1.dump -new 2.0.0.dump
kai@esoc:~/2023_iT_CMake/Day17/lib$ tree
.
├── 1.0.0.dump
├── 1.0.1.dump
├── 2.0.0.dump <----- 生成的.dump文件⭐
├── compat_reports
│ └── NAME
│ ├── 1.0.0_to_1.0.1
│ │ └── compat_report.html
│ └── 1.0.1_to_2.0.0
│ └── compat_report.html <----- 生成的報表⭐
├── libmysqrt.so -> libmysqrt.so.2
├── libmysqrt.so.1 -> libmysqrt.so.1.0.1
├── libmysqrt.so.1.0.0
├── libmysqrt.so.1.0.1
├── libmysqrt.so.2 -> libmysqrt.so.2.0.0
└── libmysqrt.so.2.0.0
生成的報表文件 1.0.1_to_2.0.0 / compat_report.html 中顯示1.0.1版本和2.0.0版本相容性為0,因此要在手冊中提醒使用該庫的人員。
6. 使用 Release 模式重新發布2.0.0版本
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make